﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using Common.Utilities;

namespace Workflows.Components.TextMining.Collapse
{
    /// <summary>
    /// 
    /// </summary>
    public class JaccardComparer:IAttributeComparer
    {
        
        public AttributeComparerType ComparerType
        {
            get { return AttributeComparerType.ClassComparer; }
        }

        public SqlDbType FieldDbType
        {
            get { return SqlDbType.NText; }
            set { throw new NotImplementedException(); }
        }

        public double Compare(object value1, object value2, double penalty, SqlConnection conn,
                              string unevenDistTableName)
        {
            if (value1 == null || value2 == null || value1 == DBNull.Value || value2 == DBNull.Value 
                || value1.ToString().Length == 0 || value2.ToString().Length == 0)
                return 0.0;

            string[] words1 = StringUtil.Split(value1.ToString().ToLower());
            string[] words2 = StringUtil.Split(value2.ToString().ToLower());

            string[] commonWords = StringUtil.Intersection(words1, words2);
            double compareScore = 0.0;
            if (commonWords != null && commonWords.Length > 0)
            {
                string[] allWords = StringUtil.Unions(words1, words2);
                return ((double) commonWords.Length)/allWords.Length;
            }
            if (compareScore == 0)
                compareScore = penalty;
            return compareScore;
        }

        public object Merge(List<object> values, SqlConnection conn, string unevenDistTableName)
        {
            if (values == null || values.Count == 0)
                return null;

            Dictionary<object, int> countByValues = new Dictionary<object, int>();
            foreach (object obj in values)
            {
                if (obj == null)
                    continue;

                if (!countByValues.ContainsKey(obj))
                    countByValues.Add(obj, 1);
                else
                    countByValues[obj] = countByValues[obj] + 1;
            }

            // check ssn9 first
            if (countByValues.Count > 0)
            {
                object mode = null;
                int count = 0;
                foreach (object obj in countByValues.Keys)
                {
                    if (countByValues[obj] > count)
                    {
                        count = countByValues[obj];
                        mode = obj;
                    }
                }
                return mode;
            }
            else
                return null;
        }
    }
}
